<!-- eslint-disable vue/html-closing-bracket-newline -->
<template>
  <Form
    ref="formRef"
    :initial-values="initialValues"
    class="space-y-4"
    @submit="onSubmit"
  >
    <div
      v-for="{
        name,
        label,
        rules,
        type,
        placeholder,
        ...attrs
      } in formSchema.fields"
      :key="name"
      class="form-field 55555555 flex items-center gap-2"
    >
      <label
        :for="name"
        class="mb-1 block w-[50px] text-sm font-medium text-gray-700"
        >{{ label }}</label
      >
      <Field
        :id="name"
        :name="name"
        :placeholder="placeholder"
        :rules="rules"
        :type="type"
        :validate-on-blur="false"
        :validate-on-input="true"
        class="rounded-md border border-gray-300 px-3 py-2 focus:border-transparent focus:outline-none focus:ring-2 focus:ring-blue-500"
        v-bind="attrs"
      >
        <template #default="{ field, handleInput }">
          <component :is="_components(attrs, field, handleInput)" />
        </template>
      </Field>

      <ErrorMessage
        :name="toValue(name)"
        as="p"
        class="animate__animated animate__bounce mt-1 text-sm text-red-500"
      />
    </div>

    <!-- 按钮组 -->
    <div class="flex gap-4">
      <button
        class="flex-1 rounded-md bg-blue-500 px-4 py-2 text-white hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
        type="submit"
      >
        提交表单
      </button>
      <button
        class="flex-1 rounded-md bg-green-500 px-4 py-2 text-white hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2"
        type="button"
        @click="setValues"
      >
        设置值
      </button>
      <button
        class="flex-1 rounded-md bg-gray-500 px-4 py-2 text-white hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2"
        type="button"
        @click="resetForm"
      >
        重置表单
      </button>
    </div>
  </Form>
</template>
<script setup lang="tsx">
import { ref, toValue } from 'vue';

import { toTypedSchema } from '@vee-validate/zod';
import {
  ElButton,
  ElInput,
  ElMessage,
  ElRadio,
  ElRadioGroup,
} from 'element-plus';
import { ErrorMessage, Field, Form, type FormContext } from 'vee-validate';
import z from 'zod';

import 'animate.css';

const formRef = ref<FormContext | null>();
const onSubmit = (_values: any, { resetForm }: any) => {
  // 表单验证通过后的处理逻辑
  ElMessage.success(`提交成功 ${JSON.stringify(_values)}`);
  // 方法1: 使用 FormActions 对象重置表单（推荐）
  resetForm();
};

// 组件映射函数（暂时未使用）
const _components = (data: any, field: any, handleInput: any) => {
  const { component, ...attrs } = data;
  switch (component) {
    case 'ElButton': {
      return (
        <ElButton
          onClick={() => handleInput('牛马')}
          size="large"
          type="primary"
        >
          {field.value}
        </ElButton>
      );
    }
    case 'ElInput': {
      return (
        <div>
          <ElInput
            onInput={(e) => handleInput(e)}
            v-bind={attrs.componentProps}
            v-model={field.value}
          />
        </div>
      );
    }
    case 'ElRadio': {
      return (
        <ElRadioGroup
          onChange={(e) => handleInput(e)}
          v-bind={attrs.componentProps}
          v-model={field.value}
        >
          {attrs.componentProps.options.map((item: any) => (
            <ElRadio key={item.value} value={item.value}>
              {item.label}
            </ElRadio>
          ))}
        </ElRadioGroup>
      );
    }
  }
};
// 设置值`
const setValues = () => {
  if (formRef.value) {
    formRef.value.setValues({
      email: 'ummm@example.com',
      password: 'P@$$w0Rd',
    });
    // 表单已重置
  } else {
    // 表单实例未找到
  }
};

// 重置表单
const resetForm = () => {
  if (formRef.value) {
    // 使用 handleReset 方法，这是官方推荐的方式
    formRef.value.resetForm({
      values: {
        name: '',
        email: '',
        password: '',
        confirmPassword: '',
        age: '',
      },
    });
  }
};

// 定义表单验证模式
const formSchema = {
  fields: [
    {
      label: '性别',
      name: 'gender',
      component: 'ElRadio',
      componentProps: {
        options: [
          { label: '男', value: '男' },
          { label: '女', value: '女' },
        ],
      },
      placeholder: '请选择性别',
      rules: toTypedSchema(z.string().min(1, { message: '请选择性别' })),
    },
    {
      label: '姓名',
      name: 'name',
      component: 'ElButton',

      placeholder: '请输入您的姓名',
      rules: toTypedSchema(
        z
          .string({
            message: '姓名至少需要2个字符',
          })
          .min(2, { message: '姓名至少需要2个字符' }),
      ),
    },
    {
      label: '邮箱',
      name: 'email',
      component: 'ElInput',

      type: 'email',
      placeholder: '请输入您的邮箱',
      rules: toTypedSchema(
        z
          .string({
            message: '请输入有效的邮箱地址',
          })
          .email({ message: '请输入有效的邮箱地址' }),
      ),
    },

    {
      label: '水果',
      name: 'radio',
      type: 'radio',
      placeholder: '请选择水果',
    },
    {
      label: '苹果',
      name: 'radio',
      type: 'radio',
      placeholder: '请选择',
    },
    {
      label: '香蕉',
      name: 'radio',
      type: 'radio',
      placeholder: '请选择',
    },
    {
      label: '确认密码',
      name: 'confirmPassword',
      as: 'input',
      type: 'password',
      placeholder: '请再次输入密码',
      rules: toTypedSchema(z.string().min(1, { message: '请确认密码' })),
    },
    {
      label: '年龄',
      name: 'age',
      as: 'input',
      type: 'number',
      placeholder: '请输入年龄',
    },
  ],
};
// // 初始值
const initialValues = {
  gender: '男',
  name: '张三',
  email: 'zhangsan@example.com',
  password: '123456',
  confirmPassword: '123456',
  age: 20,
};
</script>

<style scoped>
.form-field {
  margin-bottom: 1rem;
}
</style>
